package com.yc.cloud.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.cloud.admin.dto.request.HwCameraTimeSlotCreateReqDTO;
import com.yc.cloud.admin.dto.request.HwCameraTimeSlotQueryReqDTO;
import com.yc.cloud.admin.dto.request.HwCameraTimeSlotUpdateReqDTO;
import com.yc.cloud.admin.service.HwCameraTimeSlotService;
import com.yc.cloud.admin.vo.HwCameraTimeSlotVo;
import com.yc.cloud.common.basic.dto.BasePageReqDTO;
import com.yc.cloud.common.basic.exception.Asserts;
import com.yc.cloud.common.orm.CommonPage;
import com.yc.cloud.entity.HwCameraSnapshotTimeslotRelation;
import com.yc.cloud.entity.HwCameraStorageStrategyTimeslotRelation;
import com.yc.cloud.entity.HwCameraTimeSlot;
import com.yc.cloud.mapper.HwCameraSnapshotTimeslotRelationMapper;
import com.yc.cloud.mapper.HwCameraStorageStrategyTimeslotRelationMapper;
import com.yc.cloud.mapper.HwCameraTimeSlotMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 摄像头时间段配置表 服务实现类
 * </p>
 *
 * @author kinggu
 * @since 2025-10-14
 */
@Service
public class HwCameraTimeSlotServiceImpl extends ServiceImpl<HwCameraTimeSlotMapper, HwCameraTimeSlot> implements HwCameraTimeSlotService {

    @Resource
    private HwCameraStorageStrategyTimeslotRelationMapper storageTimeslotRelationMapper;

    @Resource
    private HwCameraSnapshotTimeslotRelationMapper snapshotTimeslotRelationMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HwCameraTimeSlotVo create(HwCameraTimeSlotCreateReqDTO createReqDTO) {
        HwCameraTimeSlot entity = new HwCameraTimeSlot();
        BeanUtils.copyProperties(createReqDTO, entity);
        boolean success = save(entity);
        if (success) {
            return getVOById(entity.getId());
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HwCameraTimeSlotVo update(HwCameraTimeSlotUpdateReqDTO updateReqDTO) {
        // 1. 校验待更新的记录是否存在
        if (getById(updateReqDTO.getId()) == null) {
            Asserts.fail("记录不存在，无法更新");
        }
        HwCameraTimeSlot entity = new HwCameraTimeSlot();
        BeanUtils.copyProperties(updateReqDTO, entity);
        boolean success = updateById(entity);
        if (success) {
            return getVOById(entity.getId());
        }
        return null;
    }

    @Override
    public HwCameraTimeSlotVo getVOById(Long id) {
        HwCameraTimeSlot entity = getById(id);
        return convertToVo(entity);
    }

    @Override
    public List<HwCameraTimeSlotVo> convertToVoList(List<HwCameraTimeSlot> entityList) {
        if (entityList == null) {
            return null;
        }
        return entityList.stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());
    }

    private HwCameraTimeSlotVo convertToVo(HwCameraTimeSlot entity) {
        if (entity == null) {
            return null;
        }
        HwCameraTimeSlotVo vo = new HwCameraTimeSlotVo();
        BeanUtils.copyProperties(entity, vo);
        // 自动计算是否跨日
        vo.setCrossDay(entity.isCrossDay());
        return vo;
    }

    @Override
    public HwCameraTimeSlot get(Long id) {
        return getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        // 1. 校验待删除的记录是否存在
        if (getById(id) == null) {
            Asserts.fail("记录不存在，无法删除");
        }
        return removeById(id);
    }

    @Override
    public CommonPage<HwCameraTimeSlotVo> list(HwCameraTimeSlotQueryReqDTO queryReqDTO) {
        QueryWrapper<HwCameraTimeSlot> queryWrapper = new QueryWrapper<>();

        // 状态过滤
        if (queryReqDTO.getStatus() != null) {
            queryWrapper.eq(HwCameraTimeSlot.Status, queryReqDTO.getStatus());
        }

        // 时间段名称模糊查询
        if (StrUtil.isNotEmpty(queryReqDTO.getSlotName())) {
            queryWrapper.like(HwCameraTimeSlot.SlotName, queryReqDTO.getSlotName());
        }

        // 排序
        if (StrUtil.isNotEmpty(queryReqDTO.getSortBy())) {
            if (Objects.equals(BasePageReqDTO.ORDER_DESC, queryReqDTO.getOrder())) {
                queryWrapper.orderByDesc(StrUtil.toUnderlineCase(queryReqDTO.getSortBy()));
            } else {
                queryWrapper.orderByAsc(StrUtil.toUnderlineCase(queryReqDTO.getSortBy()));
            }
        }

        // 根据 page 参数决定是否分页
        if (Boolean.TRUE.equals(queryReqDTO.getPage())) {
            Page<HwCameraTimeSlot> page = new Page<>(queryReqDTO.getPageNum(), queryReqDTO.getPageSize());
            Page<HwCameraTimeSlot> dbPage = baseMapper.selectPage(page, queryWrapper);
            IPage<HwCameraTimeSlotVo> voPage = dbPage.convert(this::convertToVo);
            return CommonPage.restPage(voPage);
        } else {
            List<HwCameraTimeSlot> allRecords = baseMapper.selectList(queryWrapper);
            CommonPage<HwCameraTimeSlotVo> result = new CommonPage<>();
            result.setList(convertToVoList(allRecords));
            result.setTotal((long) allRecords.size());
            result.setPageNum(1);
            result.setPageSize(allRecords.size());
            result.setTotalPage(1);
            return result;
        }
    }

    @Override
    public List<HwCameraTimeSlotVo> getTimeslotsByStorageStrategyId(Long strategyId) {
        // 获取录像策略关联的时间段ID列表
        List<Long> timeSlotIds = storageTimeslotRelationMapper.selectList(
            new QueryWrapper<HwCameraStorageStrategyTimeslotRelation>()
                .eq(HwCameraStorageStrategyTimeslotRelation.StrategyId, strategyId)
                .eq(HwCameraStorageStrategyTimeslotRelation.Status, 1)
        ).stream().map(HwCameraStorageStrategyTimeslotRelation::getTimeSlotId).collect(Collectors.toList());

        if (timeSlotIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 根据时间段ID列表查询时间段信息
        List<HwCameraTimeSlot> timeSlots = baseMapper.selectList(
            new QueryWrapper<HwCameraTimeSlot>()
                .in(HwCameraTimeSlot.ID, timeSlotIds)
                .eq(HwCameraTimeSlot.Status, 1)
                .eq(HwCameraTimeSlot.IsDeleted, 0)
        );

        return convertToVoList(timeSlots);
    }

    @Override
    public List<HwCameraTimeSlotVo> getTimeslotsBySnapshotStrategyId(Long strategyId) {
        // 获取抓拍策略关联的时间段ID列表
        List<Long> timeSlotIds = snapshotTimeslotRelationMapper.selectList(
            new QueryWrapper<HwCameraSnapshotTimeslotRelation>()
                .eq(HwCameraSnapshotTimeslotRelation.StrategyId, strategyId)
                .eq(HwCameraSnapshotTimeslotRelation.Deleted, false)
        ).stream().map(HwCameraSnapshotTimeslotRelation::getTimeSlotId).collect(Collectors.toList());

        if (timeSlotIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 根据时间段ID列表查询时间段信息
        List<HwCameraTimeSlot> timeSlots = baseMapper.selectList(
            new QueryWrapper<HwCameraTimeSlot>()
                .in(HwCameraTimeSlot.ID, timeSlotIds)
                .eq(HwCameraTimeSlot.Status, 1)
                .eq(HwCameraTimeSlot.IsDeleted, 0)
        );

        return convertToVoList(timeSlots);
    }
}

